// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
// This source file is part of the Cangjie project, licensed under Apache-2.0
// with Runtime Library Exception.
//
// See https://cangjie-lang.cn/pages/LICENSE for license information.

#include <fstream>
#include <memory>

#include "TomlFile.h"

CangjieMigrator::TomlConfig::TomlConfig(std::string title) : title(std::move(title)), pairs({})
{}

const std::string &CangjieMigrator::TomlConfig::operator[](std::string &&key) const
{
    static const std::string empty{};
    if (pairs.find(key) == pairs.end()) {
        return empty;
    }
    return pairs.at(key);
}

static std::string Trim(const std::string &str)
{
    size_t first = str.find_first_not_of(" \t");
    size_t last = str.find_last_not_of(" \t");
    return (first == std::string::npos) ? "" : str.substr(first, (last - first + 1));
}

static std::string ParseValue(const std::string &value)
{
    std::string trimmedValue = Trim(value);
    if (!trimmedValue.empty() && trimmedValue.front() == '"' && trimmedValue.back() == '"') {
        // 1 表示跳过开头的双引号，2 表示去掉结尾的双引号后的长度
        return trimmedValue.substr(1, trimmedValue.size() - 2);
    }
    return trimmedValue;
}

bool CangjieMigrator::TomlFile::ReadFile(const Path &filePath)
{
    std::ifstream file(filePath);
    if (!file) {
        return false;
    }

    std::string line;
    std::unique_ptr<TomlConfig> config = nullptr;

    while (std::getline(file, line)) {
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();  // Remove carriage return from Windows line endings
        }

        // Remove inline comments if '#' is outside quoted strings
        bool inQuotes = false;
        for (size_t i = 0; i < line.size(); ++i) {
            char c = line[i];
            if (c == '"') {
                inQuotes = !inQuotes;
            } else if (c == '#' && !inQuotes) {
                line = line.substr(0, i);
                break;
            }
        }

        if (line.empty()) {
            continue;  // Skip empty or comment-only lines
        }

        auto start = line.find("[[");
        if (start == std::string::npos) {
            if (!config) {
                continue;  // No active config block to populate
            }

            auto equal = line.find('=');
            if (equal == std::string::npos) {
                continue;  // Invalid key-value line
            }

            auto key = Trim(line.substr(0, equal));
            auto value = Trim(line.substr(equal + 1));
            config->pairs[key] = ParseValue(value);
            continue;
        }

        // Save previous config if any
        if (config) {
            configs.emplace_back(std::move(config));
        }

        auto end = line.find("]]", start);
        if (end == std::string::npos) {
            continue;  // Malformed block header
        }

        // 2 is for extract the section title between [[ and ]]
        config = std::make_unique<TomlConfig>(line.substr(start + 2, end - start - 2));
    }

    if (config) {
        configs.emplace_back(std::move(config));
    }

    return true;
}

bool CangjieMigrator::TomlFile::ReadDirectory(const Path &directory)
{
    bool success = false;

    if (!FileSystem::exists(directory) || !FileSystem::is_directory(directory)) {
        return false;
    }

    for (const auto &entry : FileSystem::directory_iterator(directory)) {
        auto file = entry.path();
        if (file.extension().string() != ".toml") {
            continue;
        }
        if (!ReadFile(file)) {
            continue;
        }
        success = true;
    }

    return success;
}

bool CangjieMigrator::TomlFile::IsEmpty() const
{
    return configs.empty();
}
